home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / emacs / emacs1857 / src_d2.zoo / source / keymap.c < prev    next >
C/C++ Source or Header  |  1991-12-02  |  33KB  |  1,322 lines

  1. /* Manipulation of keymaps
  2.    Copyright (C) 1985, 1986, 1987, 1988, 1990 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /**  
  21.  **  (sjk)++ a funky cast, keep gcc quiet.
  22.  **/
  23. #ifdef atarist
  24. static int insert_first_line();
  25. #endif
  26.  
  27. #include "config.h"
  28. #include <stdio.h>
  29. #undef NULL
  30. #include "lisp.h"
  31. #include "commands.h"
  32. #include "buffer.h"
  33.  
  34. #define min(a, b) ((a) < (b) ? (a) : (b))
  35.  
  36. /* Actually allocate storage for these variables */
  37.  
  38. #ifdef HAVE_X_WINDOWS
  39. Lisp_Object MouseMap;        /* Keymap for mouse commands */
  40. #endif /* HAVE_X_WINDOWS */
  41.  
  42. Lisp_Object global_map;
  43.  
  44. Lisp_Object Vglobal_map;
  45.  
  46. Lisp_Object Vesc_map;
  47.  
  48. Lisp_Object Vctl_x_map;
  49.  
  50. /* Keymap used for minibuffers with self-inserting space.  */
  51. Lisp_Object Vminibuffer_local_map;
  52.  
  53. /* Keymap used for minibuffers when space does not self insert.  */
  54. Lisp_Object Vminibuffer_local_ns_map;            
  55.  
  56. /* Keymap used for minibuffers when doing completion */
  57. Lisp_Object Vminibuffer_local_completion_map;
  58.  
  59. /* Keymap used for minibuffers when doing completion and require a match */
  60. Lisp_Object Vminibuffer_local_must_match_map;
  61.  
  62. Lisp_Object Qkeymapp, Qkeymap;
  63.  
  64. /* A char over 0200 in a key sequence
  65.    is equivalent to prefixing with this character.  */
  66.  
  67. extern int meta_prefix_char;
  68.  
  69. DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 0, 0,
  70.   "Construct and return a new keymap, a vector of length 128.\n\
  71. All entries in it are nil, meaning \"command undefined\".")
  72.   ()
  73. {
  74.   register Lisp_Object val;
  75.   XFASTINT (val) = 0200;
  76.   return Fmake_vector (val, Qnil);
  77. }
  78.  
  79. DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 0, 0,
  80.   "Construct and return a new sparse-keymap list.\n\
  81. Its car is 'keymap and its cdr is an alist of (CHAR . DEFINITION).\n\
  82. Initially the alist is nil.")
  83.   ()
  84. {
  85.   return Fcons (Qkeymap, Qnil);
  86. }
  87.  
  88. /* Install a standard key binding at initialization time.
  89.    For example,
  90.      ndefkey (Vctl_x_map, Ctl ('X'), "exchange-point-and-mark");  */
  91.  
  92. void
  93. ndefkey (keymap, key, defname)
  94.      Lisp_Object keymap;
  95.      int key;
  96.      char *defname;
  97. {
  98.   store_in_keymap (keymap, key, intern (defname));
  99. }
  100.  
  101. /* Define character fromchar in map frommap as an alias for character tochar in map tomap.
  102.  Subsequent redefinitions of the latter WILL affect the former. */
  103.  
  104. #ifdef NOTDEF
  105. void
  106. synkey (frommap, fromchar, tomap, tochar)
  107.      struct Lisp_Vector *frommap, *tomap;
  108.      int fromchar, tochar;
  109. {
  110.   Lisp_Object v, c;
  111.   XSET (v, Lisp_Vector, tomap);
  112.   XFASTINT (c) = tochar;
  113.   frommap->contents[fromchar] = Fcons (v, c);
  114. }
  115. #endif /* NOTDEF */
  116.  
  117. DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
  118.   "Return t if ARG is a keymap.\n\
  119. A keymap is a vector of length 128, or a list (keymap . ALIST),\n\
  120. where alist elements look like (CHAR . DEFN).")
  121.   (object)
  122.      Lisp_Object object;
  123. {
  124.   register Lisp_Object tem;
  125.   tem = object;
  126.   while (XTYPE (tem) == Lisp_Symbol)
  127.     {
  128.       tem = XSYMBOL (tem)->function;
  129.       if (EQ (tem, Qunbound))
  130.     return Qnil;
  131.       QUIT;
  132.     }
  133.  
  134.   if ((XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == 0200)
  135.       || (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap)))
  136.     return Qt;
  137.   return Qnil;
  138. }
  139.  
  140. Lisp_Object
  141. get_keymap_1 (object, error)
  142.      Lisp_Object object;
  143.      int error;
  144. {
  145.   register Lisp_Object tem;
  146.  
  147.   while (1)
  148.     {
  149.       tem = object;
  150.       while (XTYPE (tem) == Lisp_Symbol && !EQ (tem, Qunbound))
  151.     {
  152.       tem = XSYMBOL (tem)->function;
  153.       QUIT;
  154.     }
  155.       if ((XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == 0200)
  156.       || (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap)))
  157.     return tem;
  158.       if (error)
  159.     object = wrong_type_argument (Qkeymapp, object);
  160.       else return Qnil;
  161.     }
  162. }
  163.  
  164. Lisp_Object
  165. get_keymap (object)
  166.      Lisp_Object object;
  167. {
  168.   return get_keymap_1 (object, 1);
  169. }
  170.  
  171. Lisp_Object
  172. get_keyelt (object)
  173.      register Lisp_Object object;
  174. {
  175.   register Lisp_Object map, tem;
  176.  
  177.   while (map = get_keymap_1 (Fcar_safe (object), 0),
  178.      tem = Fkeymapp (map),
  179.      !NULL (tem))
  180.       /*(XTYPE (object) == Lisp_Cons && !EQ (XCONS (object)->car, Qkeymap))*/
  181.     {
  182.       object = Fcdr (object);
  183.       if (CONSP (map))
  184.     object = Fcdr (Fassq (object, Fcdr (map)));
  185.       else
  186.     object = Faref (map, object);
  187.     }
  188.   return object;
  189. }
  190.  
  191. Lisp_Object
  192. access_keymap (map, idx)
  193.      Lisp_Object map;
  194.      register int idx;
  195. {
  196.   register Lisp_Object val;
  197.   if (idx < 0 || idx >= 0200)
  198.     error ("Command key out of range 0-127");
  199.  
  200.   /* Get definition for character `idx' proper.  */
  201.   if (CONSP (map))
  202.     val = Fcdr (Fassq (make_number (idx), Fcdr (map)));
  203.   else
  204.     val = XVECTOR (map)->contents[idx];
  205.  
  206.   return val;
  207. }
  208.  
  209. Lisp_Object
  210. store_in_keymap (keymap, idx, def)
  211.      Lisp_Object keymap;
  212.      register int idx;
  213.      register Lisp_Object def;
  214. {
  215.   register Lisp_Object tem;
  216.  
  217.   if (idx < 0 || idx >= 0200)
  218.     error ("Command key out of range 0-127");
  219.  
  220.   if (CONSP (keymap))
  221.     {
  222.       tem = Fassq (make_number (idx), Fcdr (keymap));
  223.       if (!NULL (tem))
  224.     Fsetcdr (tem, def);
  225.       else
  226.     Fsetcdr (keymap, Fcons (Fcons (make_number (idx), def),
  227.                 Fcdr (keymap)));
  228.     }
  229.   else
  230.     XVECTOR (keymap)->contents[idx] = def;
  231.  
  232.   return def;
  233. }
  234.  
  235. DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0,
  236.   "Return a copy of the keymap KEYMAP.\n\
  237. The copy starts out with the same definitions of KEYMAP,\n\
  238. but changing either the copy or KEYMAP does not affect the other.\n\
  239. Any key definitions that are subkeymaps are recursively copied.")
  240.   (keymap)
  241.      Lisp_Object keymap;
  242. {
  243.   register Lisp_Object copy, tem;
  244.  
  245.   keymap = get_keymap (keymap);
  246.   if (XTYPE (keymap) == Lisp_Vector)
  247.     {
  248.       register int i;
  249.       copy = Fcopy_sequence (keymap);
  250.       for (i = 0; i < XVECTOR (copy)->size; i++)
  251.     if (tem = Fkeymapp (XVECTOR (copy)->contents[i]), !NULL (tem))
  252.       XVECTOR (copy)->contents[i] = Fcopy_keymap (XVECTOR (copy)->contents[i]);
  253.     }
  254.   else
  255.     {
  256.       register Lisp_Object tail;
  257.       copy = Fcopy_alist (keymap); 
  258.       for (tail = copy; CONSP (tail); tail = XCONS (tail)->cdr)
  259.     {
  260.       register Lisp_Object elt;
  261.       elt = XCONS (tail)->car;
  262.       if (CONSP (elt) && (tem = Fkeymapp (XCONS (elt)->cdr), !NULL (tem)))
  263.         XCONS (elt)->cdr = Fcopy_keymap (XCONS (elt)->cdr);
  264.     }
  265.     }
  266.   return copy;
  267. }
  268.  
  269. DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 3, 0,
  270.   "Args KEYMAP, KEY, DEF.  Define key sequence KEY, in KEYMAP, as DEF.\n\
  271. KEYMAP is a keymap.  KEY is a string meaning a sequence of keystrokes.\n\
  272. DEF is anything that can be a key's definition:\n\
  273.  nil (means key is undefined in this keymap),\n\
  274.  a command (a Lisp function suitable for interactive calling)\n\
  275.  a string (treated as a keyboard macro),\n\
  276.  a keymap (to define a prefix key),\n\
  277.  a list (KEYMAP . CHAR), meaning use definition of CHAR in map KEYMAP,\n\
  278.  or a symbol.  The symbol's function definition is used as the key's\n\
  279. definition, and may be any of the above (including another symbol).")
  280.   (keymap, key, def)
  281.      register Lisp_Object keymap;
  282.      Lisp_Object key;
  283.      Lisp_Object def;
  284. {
  285.   register int idx;
  286.   register int c;
  287.   register Lisp_Object tem;
  288.   register Lisp_Object cmd;
  289.   int metized = 0;
  290.  
  291.   keymap = get_keymap (keymap);
  292.  
  293.   CHECK_STRING (key, 1);
  294.   if (XSTRING (key)->size == 0)
  295.     return Qnil;
  296.  
  297.   idx = 0;
  298.   while (1)
  299.     {
  300.       c = XSTRING (key)->data[idx];
  301.       if (c >= 0200 && !metized)
  302.     {
  303.       c = meta_prefix_char;
  304.       metized = 1;
  305.     }
  306.       else
  307.     {
  308.       c &= 0177;
  309.       metized = 0;
  310.       idx++;
  311.     }
  312.  
  313.       if (idx == XSTRING (key)->size)
  314.     return store_in_keymap (keymap, c, def);
  315.  
  316.       cmd = get_keyelt (access_keymap (keymap, c));
  317.       if (NULL (cmd))
  318.     {
  319.       cmd = Fmake_sparse_keymap ();
  320.       store_in_keymap (